package com.ziq.zcamp.util

import android.annotation.SuppressLint
import android.os.Build
import com.ziq.zcamp.util.io.IOUtils
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader

/**
 * 应用系统版本帮助类
 *
 */
object OSHelper {
    private const val ROM_MIUI = "MIUI"
    private const val ROM_EMUI = "EMUI"
    private const val ROM_OPPO = "OPPO"
    private const val ROM_VIVO = "VIVO"
    private const val ROM_FLYME = "FLYME"
    private const val ROM_SAMSUNG = "SAMSUNG"

    //oppo同一家
    private const val ROM_ONEPLUS = "ONEPLUS"
    private const val ROM_REALME = "REALME"

    private const val KEY_VERSION_MIUI = "ro.miui.ui.version.name"
    private const val KEY_VERSION_EMUI = "ro.build.version.emui"
    private const val KEY_VERSION_OPPO = "ro.build.version.opporom"
    private const val KEY_VERSION_VIVO = "ro.vivo.os.version"

    private var sName: String? = null
    private var sVersion: String? = null

    fun isEmUI(): Boolean {
        return check(ROM_EMUI)
    }

    fun getEmUI(): EmUI? {
        return if (check(ROM_EMUI)) {
            EmUI(sName ?: "", sVersion ?: "")
        } else {
            null
        }
    }

    fun isMiUI(): Boolean {
        return check(ROM_MIUI)
    }

    fun isVivo(): Boolean {
        return check(ROM_VIVO)
    }

    fun isOppo(): Boolean {
        return check(ROM_OPPO) || check(ROM_ONEPLUS) || check(ROM_REALME)
    }

    fun isFlyme(): Boolean {
        return check(ROM_FLYME)
    }

    fun isSamsung(): Boolean {
        return check(ROM_SAMSUNG)
    }

    @SuppressLint("DefaultLocale")
    fun check(rom: String): Boolean {
        if (sName != null) {
            return sName == rom
        }
        sName = when {
            getProp(KEY_VERSION_MIUI).isNotBlank() -> ROM_MIUI
            getProp(KEY_VERSION_EMUI).isNotBlank() -> ROM_EMUI
            getProp(KEY_VERSION_OPPO).isNotBlank() -> ROM_OPPO
            getProp(KEY_VERSION_VIVO).isNotBlank() -> ROM_VIVO
            Build.DISPLAY.contains(ROM_FLYME, true) -> ROM_FLYME
            Build.MANUFACTURER.contains(ROM_SAMSUNG, true) -> ROM_SAMSUNG
            Build.MANUFACTURER.contains(ROM_ONEPLUS, true) -> ROM_ONEPLUS
            Build.MANUFACTURER.contains(ROM_REALME, true) -> ROM_REALME
            else -> Build.MANUFACTURER.toUpperCase()
        }
        return sName == rom
    }

    private fun getProp(name: String): String {
        var input: BufferedReader? = null
        try {
            val p = Runtime.getRuntime().exec("getprop $name")
            input = BufferedReader(InputStreamReader(p.inputStream), 1024)
            sVersion = input.readLine()
        } catch (ex: IOException) {
            sVersion = ""
        } finally {
            IOUtils.closeQuietly(input)
        }
        return sVersion ?: ""
    }
}

/**
 * 系统版本封装类
 */
abstract class OS(val name: String, val version: String) {
    /**
     * 判断版本号
     */
    open fun isVersionAbove(version: String): Boolean {
        return false
    }

    /**
     * 判断版本号
     */
    open fun isVersionBelow(version: String): Boolean {
        return false
    }

    /**
     * 判断版本号
     */
    open fun isVersionEquals(version: String): Boolean {
        return false
    }

    /**
     * 默认厂商
     */
    fun manufacturer(): String {
        return Build.MANUFACTURER
    }

    /**
     * 默认手机型号
     */
    fun model(): String {
        return Build.MODEL
    }

    /**
     * 默认手机sdk版本
     */
    fun sdk(): Int {
        return Build.VERSION.SDK_INT
    }
}

/**
 * 华为系统版本封装类
 */
class EmUI(name: String, version: String) : OS(name, version) {
    /**
     * 返回当前EmUI系统版本
     */
    private val ver: EmUIVersion by lazy {
        return@lazy EmUIVersion(version)
    }

    override fun toString(): String {
        return "EmUI(name=$name, version=$version, ver=$ver)"
    }

    override fun isVersionBelow(version: String): Boolean {
        if (version.isBlank()) return false
        val v = EmUIVersion(version)
        return ver.major < v.major
    }

    /**
     * 判断系统版本
     */
    override fun isVersionAbove(version: String): Boolean {
        if (version.isBlank()) return false
        val v = EmUIVersion(version)
        return ver.major > v.major
    }

    override fun isVersionEquals(version: String): Boolean {
        if (version.isBlank()) return false
        val v = EmUIVersion(version)
        return ver.major == v.major && ver.sub == v.sub && ver.phase == v.phase
    }

    /**
     * 华为版本号类封装
     */
    class EmUIVersion(version: String) {
        val major: Int
        val sub: Int
        val phase: Int

        init {
            val idx = version.indexOf("_")
            val v = if (idx >= 0) {
                try {
                    version.substring(idx + 1)
                } catch (ex: Exception) {
                    ""
                }
            } else {
                version
            }
            if (v.isNotBlank()) {
                val ver = v.split(".")
                if (ver.isNotEmpty()) {
                    major = try {
                        ver[0].toInt()
                    } catch (ex: Exception) {
                        0
                    }
                    sub = if (ver.size > 1) {
                        try {
                            ver[1].toInt()
                        } catch (ex: Exception) {
                            0
                        }
                    } else {
                        0
                    }
                    phase = if (ver.size > 2) {
                        try {
                            ver[2].toInt()
                        } catch (ex: Exception) {
                            0
                        }
                    } else {
                        0
                    }
                } else {
                    major = 0
                    sub = 0
                    phase = 0
                }
            } else {
                major = 0
                sub = 0
                phase = 0
            }
        }

        override fun toString(): String {
            return "EmUIVersion(major=$major, sub=$sub, phase=$phase)"
        }
    }
}